#include <string.h>

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
// g++ -o cpp_file cpp_file.cc -std=c++11

// 一次读取整个文件的内容：方法一,保存到char数组
void test1(const std::string& path) {
  std::ifstream ifs;
  ifs.open(path, ios::in | ios::binary);
  ifs.seekg(0, ios::end);
  int len = ifs.tellg();
  cout << len << endl;
  ifs.seekg(0, ios::beg);
  char* buffer = new char[len];
  ifs.read(buffer, len);
  ifs.close();
  // 拷贝一份
  // ofstream ofs("1.jpg", ios::out);  // 名字为1,vscode不能打开
  // ofs.write(buffer, len);
  // ofs.close();

  // cout << buffer << endl;  //
  // FIXME:为什么文本文件成功显示内容，而二进制文件显示失败，但内容是在buffer里的，可以输出到一个ofs？？
  delete buffer;
}

// 一次读取整个文件的内容：方法二，,保存到string
std::string test2(const std::string& path) {
  ifstream ifs;
  ifs.open(path, ios::in);
  std::string str((std::istreambuf_iterator<char>(ifs)),
                  std::istreambuf_iterator<char>());
  // cout << str << endl;
  ifs.close();
  return str;
}
// 一次读取整个文件的内容：方法三,保存到string
std::string test3(const std::string& path) {
  ifstream ifs;
  ifs.open(path, ios::in);
  std::stringstream buffer;
  buffer << ifs.rdbuf();
  std::string str(buffer.str());
  // cout << str << endl;
  ifs.close();
  return str;
}

// 拷贝一个文本文件
void test4(const std::string& src_path, const std::string& dst_path) {
  ifstream ifs;
  ifs.open(src_path, ios::in);
  string res;
  string tmp;
  // 不跳过任何前导空格，如果没有前导空白，则标志不会产生影响。
  ifs >> std::noskipws;
  //   while (!ifs.eof()) {
  //     ifs >>
  //         tmp;  //
  //         遇到空白字符会停止读取;读取了多少字节文件指针也相应地移动多少
  //     res += tmp;
  //   }

  while (getline(ifs, tmp, '\n')) {  // 仅忽略行尾的换行符
    res += tmp + "\n";
  }
  cout << res << "@" << endl;
  ifs.close();
  ofstream ofs;
  ofs.open(dst_path, ios::out);
  ofs << res;
}

// 拷贝一个二进制文件
void test5(const std::string& src_path, const std::string& dst_path) {
  std::string str = test2(src_path);
  ofstream ofs(dst_path, ios::binary | ios::out);
  ofs << str;
  ofs.close();
}
// linux上文件文件和二进制文件没有区别，一摸一样
int main() {
  // test1();
  // test2();
  // test3();
  // test4();
  // test5();
  return 0;
}